package com.openapi.handle;

import com.common.utils.R;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * REST接口统一的日志处理
 */
@Aspect
@Component
public class LogHandle {
    private static final Logger logger = LoggerFactory.getLogger(LogHandle.class);

    @Pointcut("execution(public * com.openapi.controller..*.*(..))")
    public void restLog() {
    }

    @Around("restLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        joinPoint.getArgs();
        Object result = R.error(1000, "接口调用失败！");
        try {

            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();

            String url = request.getRequestURL().toString();
            String method = request.getMethod();
            String uri = request.getRequestURI();
            logger.info("接口调用======> url: " + url + ",method:" + method + ",uri:" + uri + ",paramString:" + Arrays.toString(joinPoint.getArgs()));

            // result的值就是被拦截方法的返回值
            result = joinPoint.proceed();
            String resultStr = result == null ? "" : result.toString();
            logger.info("接口返回=====>" + resultStr);

        } catch (Throwable e) {
            logger.error("接口调用出错：" + e.getMessage() + "" + getExceptionInfo(e));
        } finally {
            return result;
        }
    }


    public static String getExceptionInfo(Throwable ex) {
        String sOut = "";
        StackTraceElement[] trace = ex.getStackTrace();
        for (StackTraceElement s : trace) {
            sOut += "\tat " + s + "\r\n";
        }
        return sOut;
    }


}
